package eth

import (
	"fmt"
	"net"

	"gitee.com/liumou_site/logger"
)

// GetDefaultIPInfo 获取本机默认网络接口的IP信息
//
// 该函数通过以下步骤获取本机默认IP信息：
// 1. 获取系统默认网络接口
// 2. 获取该接口的IPv4地址信息
//
// 返回值:
//
//	*Info - 包含默认网卡信息的结构体指针
//	error - 如果发生错误，则返回错误信息，否则返回nil
func GetDefaultIPInfo() (*Info, error) {
	// 创建Eth实例
	e := NewEth(false)

	// 尝试获取默认网络接口
	iface, err := e.GetDefaultInterface()
	if err != nil {
		logger.Warn("通过默认路由获取网络接口失败:", err)

		// 备选方法：尝试获取所有网卡，选择第一个有效的非本地回环接口
		ethList := e.GetEthList()
		if len(ethList) == 0 {
			return nil, fmt.Errorf("未找到任何可用网络接口")
		}

		// 遍历所有网卡，选择第一个可用的网卡
		logger.Debug("尝试使用备选方法获取网络接口，可用网卡列表:", ethList)
		for _, eth := range ethList {
			info, err := e.GetEthInfoV4(eth)
			if err == nil && info != nil && len(info.Ip) > 0 {
				logger.Debug("使用备选网卡成功:", eth)

				// 修复可能存在的掩码问题
				fixMaskIssues(info)
				return info, nil
			}
		}

		return nil, fmt.Errorf("无法获取默认网络接口信息: %v", err)
	}

	// 获取默认网络接口的名称
	ifaceName := iface.Name
	logger.Debug("默认网络接口名称:", ifaceName)

	// 使用接口名称获取IPv4信息
	info, err := e.GetEthInfoV4(ifaceName)
	if err != nil {
		logger.Warn("获取默认网络接口IPv4信息失败:", err)

		// 尝试使用非IPv4特定的方法
		infoGeneral, err2 := e.GetEthInfo(ifaceName)
		if err2 != nil || infoGeneral == nil || len(infoGeneral.Ip) == 0 {
			return nil, fmt.Errorf("获取默认网络接口信息失败: %v", err)
		}

		info = infoGeneral
		logger.Debug("使用通用方法获取网络信息成功")
	}

	// 修复可能存在的掩码问题
	fixMaskIssues(info)

	return info, nil
}

// fixMaskIssues 修复网卡信息中可能存在的掩码问题
func fixMaskIssues(info *Info) {
	if info == nil || len(info.Ip) == 0 {
		return
	}

	for i := range info.Ip {
		// 检查IP是否为IPv4
		isIPv4 := info.Ip[i].Ip.To4() != nil

		if isIPv4 {
			// 修正IPv4掩码长度
			if info.Ip[i].MaskInt > 32 {
				logger.Warn("修正IPv4掩码长度超过32的异常值:", info.Ip[i].MaskInt, "->", 24)
				info.Ip[i].MaskInt = 24 // 使用常见默认值
			} else if info.Ip[i].MaskInt <= 0 {
				// 如果掩码长度为0或负数，设置为默认值24
				logger.Warn("为缺失的IPv4掩码长度设置默认值:", info.Ip[i].Ip.String(), "掩码长度:", 24)
				info.Ip[i].MaskInt = 24
			}

			// 检查掩码对象是否为nil
			if info.Ip[i].Mask == nil {
				// 根据MaskInt创建正确的掩码
				mask := net.CIDRMask(info.Ip[i].MaskInt, 32) // IPv4使用32位掩码
				info.Ip[i].Mask = net.IP(mask)
				logger.Debug("为IPv4地址创建掩码对象:", info.Ip[i].Ip.String(), "掩码:", net.IP(mask).String())
			}
		} else {
			// IPv6地址处理
			if info.Ip[i].MaskInt <= 0 {
				// IPv6默认掩码长度为64
				info.Ip[i].MaskInt = 64
			}

			// IPv6掩码对象处理
			if info.Ip[i].Mask == nil {
				mask := net.CIDRMask(info.Ip[i].MaskInt, 128) // IPv6使用128位掩码
				info.Ip[i].Mask = net.IP(mask)
			}
		}
	}

	// 如果顶层掩码为nil但至少有一个IP地址，使用第一个IP的掩码
	if info.Mask == nil && len(info.Ip) > 0 && info.Ip[0].Mask != nil {
		info.Mask = info.Ip[0].Mask
		logger.Debug("设置顶层掩码:", info.Mask.String())
	} else if info.Mask == nil && len(info.Ip) > 0 {
		// 确定是IPv4还是IPv6
		isIPv4 := info.Ip[0].Ip.To4() != nil
		maskBits := 32
		maskInt := info.Ip[0].MaskInt

		if !isIPv4 {
			maskBits = 128
			if maskInt <= 0 {
				maskInt = 64 // IPv6默认掩码长度
			}
		} else {
			if maskInt <= 0 || maskInt > 32 {
				maskInt = 24 // IPv4默认掩码长度
			}
		}

		mask := net.CIDRMask(maskInt, maskBits)
		info.Mask = net.IP(mask)
		logger.Debug("从掩码长度创建顶层掩码:", info.Mask.String())
	}
}

// GetDefaultIPv4 获取本机默认网络接口的IPv4地址
//
// 返回值:
//
//	net.IP - 默认网卡的IPv4地址
//	error - 如果发生错误，则返回错误信息，否则返回nil
func GetDefaultIPv4() (net.IP, error) {
	// 获取默认IP信息
	info, err := GetDefaultIPInfo()
	if err != nil {
		return nil, err
	}

	// 检查是否有IP信息
	if len(info.Ip) == 0 {
		return nil, fmt.Errorf("默认网卡没有IPv4地址")
	}

	// 返回第一个IP地址
	return info.Ip[0].Ip, nil
}

// GetDefaultIPv4String 获取本机默认网络接口的IPv4地址字符串表示
//
// 返回值:
//
//	string - 默认网卡的IPv4地址字符串
//	error - 如果发生错误，则返回错误信息，否则返回nil
func GetDefaultIPv4String() (string, error) {
	ip, err := GetDefaultIPv4()
	if err != nil {
		return "", err
	}

	return ip.String(), nil
}

// GetDefaultNetworkInfo 获取本机默认网络接口的完整网络信息
//
// 返回值:
//
//	map[string]interface{} - 包含网卡名称、IP地址、MAC地址、子网掩码、网关、DNS等信息的映射
//	error - 如果发生错误，则返回错误信息，否则返回nil
func GetDefaultNetworkInfo() (map[string]interface{}, error) {
	// 获取默认IP信息
	info, err := GetDefaultIPInfo()
	if err != nil {
		return nil, err
	}

	// 构建结果映射
	result := make(map[string]interface{})
	result["name"] = info.Name
	result["mac"] = info.Mac

	// 提取IP信息
	if len(info.Ip) > 0 {
		ipList := make([]string, 0, len(info.Ip))
		maskList := make([]int, 0, len(info.Ip))
		maskStrList := make([]string, 0, len(info.Ip))

		for _, ipInfo := range info.Ip {
			ipList = append(ipList, ipInfo.Ip.String())
			maskList = append(maskList, ipInfo.MaskInt)

			// 添加掩码字符串表示形式
			if ipInfo.Mask != nil {
				maskStrList = append(maskStrList, ipInfo.Mask.String())
			} else if ipInfo.MaskInt > 0 {
				// 如果没有掩码但有掩码长度，则生成掩码表示
				mask := net.CIDRMask(ipInfo.MaskInt, 32) // IPv4使用32位掩码
				maskStrList = append(maskStrList, net.IP(mask).String())
			} else {
				maskStrList = append(maskStrList, "")
			}
		}

		result["ip"] = ipList
		result["mask_int"] = maskList
		result["mask_list"] = maskStrList

		if info.Mask != nil {
			result["mask"] = info.Mask.String()
		} else if len(info.Ip) > 0 && info.Ip[0].MaskInt > 0 {
			// 如果顶层没有掩码但IP信息有掩码长度，则生成掩码
			mask := net.CIDRMask(info.Ip[0].MaskInt, 32)
			result["mask"] = net.IP(mask).String()
		}
	}

	// 添加网关信息
	// 网关信息由每个IP单独存储
	gateways := []string{}
	for _, ip := range info.Ip {
		if ip.Gw != nil {
			gateways = append(gateways, ip.Gw.String())
		}
	}
	for _, ip6 := range info.Ip6Info {
		if ip6.Gw != nil {
			gateways = append(gateways, ip6.Gw.String())
		}
	}
	if len(gateways) > 0 {
		result["gateway"] = gateways
	}

	// 添加子网信息
	if info.Sub != nil {
		result["subnet"] = info.Sub.String()
	}

	// 添加DNS信息
	if len(info.DnsList) > 0 {
		dnsList := make([]string, 0, len(info.DnsList))
		for _, dns := range info.DnsList {
			dnsList = append(dnsList, dns.String())
		}
		result["dns"] = dnsList
	}

	// 添加IP版本
	result["version"] = info.Version

	return result, nil
}

// IsPrivateIP 检查IP是否为私有IP地址
//
// 私有IP地址包括:
// - 10.0.0.0/8
// - 172.16.0.0/12
// - 192.168.0.0/16
// - 169.254.0.0/16 (链路本地地址)
//
// 参数:
//
//	ip: 要检查的IP地址
//
// 返回值:
//
//	bool: 如果是私有IP地址返回true，否则返回false
func IsPrivateIP(ip net.IP) bool {
	// 确保是IPv4地址
	ip = ip.To4()
	if ip == nil {
		return false // 非IPv4地址
	}

	// 检查是否属于私有IP地址范围

	// 10.0.0.0/8
	if ip[0] == 10 {
		return true
	}

	// 172.16.0.0/12
	if ip[0] == 172 && ip[1] >= 16 && ip[1] <= 31 {
		return true
	}

	// 192.168.0.0/16
	if ip[0] == 192 && ip[1] == 168 {
		return true
	}

	// 169.254.0.0/16 (链路本地地址)
	if ip[0] == 169 && ip[1] == 254 {
		return true
	}

	return false
}

// FormatIPv4WithMask 格式化IPv4地址和掩码
//
// 参数:
//
//	ip: IPv4地址
//	maskInt: 掩码长度（如24表示255.255.255.0）
//
// 返回值:
//
//	string: 格式化后的IP和掩码，例如"192.168.1.1/255.255.255.0"
func FormatIPv4WithMask(ip net.IP, maskInt int) string {
	if ip == nil {
		return ""
	}

	// 确保是IPv4地址
	ipv4 := ip.To4()
	if ipv4 == nil {
		return ip.String()
	}

	// 创建掩码
	if maskInt > 0 && maskInt <= 32 {
		mask := net.CIDRMask(maskInt, 32)
		return fmt.Sprintf("%s/%s", ipv4.String(), net.IP(mask).String())
	}

	return ipv4.String()
}
